#include "include.h"
#include "func.h"
#include "func_adapter.h"

#define TRACE_EN                1

#if TRACE_EN
#define TRACE(...)              printf(__VA_ARGS__)
#define TRACE_R(...)            print_r(__VA_ARGS__)
#else
#define TRACE(...)
#define TRACE_R(...)
#endif // TRACE_EN

enum {
    ADAPTER_STA_INIT_IDLE,
    ADAPTER_STA_INIT_W4_CONNECT,
    ADAPTER_STA_START_ACTION,
    ADAPTER_STA_IDLE,
};

static struct {
    uint8_t init_flag;
    uint8_t init_state;
    uint32_t ticks;
} adapter_cb;

#if WIRELESS_MIC_TX_EN
//无线MIC适配器处理流程
//ADAPTER_RX -> wireless_d2a_set_rxpkt_cb -> decoder_prio_trans_audio_input -> mic_dec_audio_input --> mic_mix_audio_input-> dac0_out_audio_input -> DAC
//                                                                                                 |-> dac0_out_audio_input -> DAC
//                                                                                                 |-> usb_mic_in_audio_input -> USB
static ws_link_list_t mic_rx_cfg_tbl[] = {
/*  模块类型，                  使能，          初始化，                    输入接口，                  设置输出*/
    {DECODER_PRIO_TRANS_TYPE,   1,              decoder_prio_trans_init,    NULL,                       decoder_prio_trans_audio_output_callback_set},
    {MIC_DEC_TYPE,              1,              mic_dec_init,               mic_dec_audio_input,        mic_dec_audio_output_callback_set},

#if ADAPTER_NR_FAR_EN || ADAPTER_ECHO_EN || ADAPTER_PLATE_REVERB_EN || ADAPTER_MAGIC_EN || ADAPTER_ROOM_REVERB_EN || ADAPTER_AINS3_EN || ADAPTER_HUART_OUTPUT_EN || ADAPTER_MIC_DRC_EN
    {DECODER_PRIO_TRANS_TYPE,   1,              alg_prio_trans_init,        alg_prio_trans_audio_input, alg_prio_trans_audio_output_callback_set},
#endif

#if ADAPTER_MIC_DRC_EN
    {EQ_DRC_TYPE,               1,              mic_eq_drc_init,          mic_eq_drc_audio_input,          mic_eq_drc_audio_output_callback_set},               //EQ
#endif

#if ADAPTER_AINS3_EN
    {AINS_TYPE,                 1,              ains3_mic_init,           ains3_mic_audio_input,           ains3_mic_output_callback_set},
#endif

#if ADAPTER_NR_FAR_EN
    {NR_FAR_TYPE,               1,              nr_far_mic_init,            nr_far_mic_input,           nr_far_mic_output_callback_set},
#endif

#if ADAPTER_ECHO_EN
    {ECHO_TYPE,                 1,              echo_audio_init,            echo_audio_input,           echo_audio_output_callback_set},
#endif

#if ADAPTER_PLATE_REVERB_EN
    {PLATE_REVERB_TYPE,         1,              plate_reverb_audio_init,    plate_reverb_audio_input,   plate_reverb_audio_output_callback_set},
#endif

#if ADAPTER_ROOM_REVERB_EN
    {ROOM_REVERB_TYPE,          1,              room_reverb_audio_init,    room_reverb_audio_input,    room_reverb_audio_output_callback_set},
#endif

#if ADAPTER_MAGIC_EN
    {MAGCI_PITCH_SHIFT_TYPE,    1,              magic_audio_init,           magic_audio_input,          magic_audio_output_callback_set},
#endif

#if ADAPTER_LOCAL_MIC_MIX_EN
    {MIC_MIX_TYPE,              1,              mic_mix_init,               mic_mix_audio_input,        mic_mix_output_callback_set},
#endif

#if ADAPTER_HUART_OUTPUT_EN
    {HUART_TX_TYPE,             1,              huart_audio_out_init,       huart_audio_out_input,      huart_audio_out_output_callback_set},
#endif

#if I2S_TX_AUDIO_EN
    {IIS_TX_TYPE,               1,              iis_tx_pool_init,           iis_tx_audio_input,         iis_tx_audio_output_callback_set},
#endif
#if ADAPTER_DAC_OUTPUT_EN
    {DAC_OUT_TYPE,              1,              dac_out_init,               dac_out_audio_input,        dac_out_audio_output_callback_set},
#endif
#if ADAPTER_USB_MIC_RX_EN
//    {SRC_TYPE,                  1,              src_init,                   src_audio_input,            src_audio_output_callback_set},
    {USB_MIC_IN_TYPE,           1,              usb_mic_in_init,            usb_mic_in_audio_input,     NULL},
#endif
};
#endif

#if ADAPTER_USB_SPK_TX_EN
static ws_link_list_t spk_tx_cfg_tbl[] = {
/*  模块类型，                 使能，            初始化，                  输入接口，                      设置输出*/
    {USB_AUDIO_OUT_TYPE,       1,                usb_audio_out_init,       NULL,                           usb_audio_out_audio_output_callback_set},
//    {ENCODER_PRIO_TRANS_TYPE,  1,                encoder_prio_trans_init,  encoder_prio_trans_audio_input, encoder_prio_trans_audio_output_callback_set},   //缓存到编码缓冲区，并转到低优先级处理
    {SRC_TYPE,                 1,                src_init,                 src_audio_input,                src_audio_output_callback_set},                  //通过SRC微调匹配速度
    {SRC_TYPE,                 1,                src_buf_init,             src_buf_audio_input,            src_buf_audio_output_callback_set},
    {SPK_ENC_TYPE,             1,                spk_enc_init,             NULL,                           spk_enc_audio_output_callback_set},              //PCM编码
#if WIRELESS_SPK_LOCAL_OUTPUT_EN
    {DAC_OUT_TYPE,             1,                dac_out_init,             dac_out_audio_input,            dac_out_audio_output_callback_set},              //DAC输出（调试SPK通路用）
#endif
};
#elif ADAPTER_AUX_TX_EN
//SPK_ADC --> encoder_prio_trans_audio_input -> spk_enc_audio_input -> wireless_a2d_put_tx_frame -> memcpy(txbuf, enc_buf, size) -> ADAPTER_TX
//        |-> dac0_out_audio_input -> DAC
static ws_link_list_t spk_tx_cfg_tbl[] = {
/*  模块类型，                 使能，            初始化，                  输入接口，                      设置输出*/
    {SPK_TYPE,                 1,                spk_init,                 NULL,                           spk_audio_output_callback_set},
    {ENCODER_PRIO_TRANS_TYPE,  1,                encoder_prio_trans_init,  encoder_prio_trans_audio_input, encoder_prio_trans_audio_output_callback_set},   //缓存到编码缓冲区，并转到低优先级处理
    {SPK_ENC_TYPE,             1,                spk_enc_init,             spk_enc_audio_input,            spk_enc_audio_output_callback_set},              //PCM编码
#if WIRELESS_SPK_LOCAL_OUTPUT_EN
    {DAC_OUT_TYPE,             1,                dac_out_init,             dac_out_audio_input,            dac_out_audio_output_callback_set},              //DAC输出（调试SPK通路用）
#endif
};
#endif

AT(.text.func.adapter)
void func_adapter_init(void)
{
    if (!wireless_role_is_adapter()) {
        return;
    }
    if (!adapter_cb.init_flag) {
        adapter_cb.init_flag = 1;
#if WIRELESS_MIC_TX_EN
        ws_link_list_init(mic_rx_cfg_tbl, (sizeof(mic_rx_cfg_tbl)/sizeof(ws_link_list_t)), WIRELESS_MIC_SAMPLE_RATE_SELECT, WIRELESS_MIC_SAMPLES_SELECT);
#endif

#if WIRELESS_SPK_TX_EN
        ws_link_list_init(spk_tx_cfg_tbl, (sizeof(spk_tx_cfg_tbl)/sizeof(ws_link_list_t)), WIRELESS_SPK_SAMPLE_RATE_SELECT, WIRELESS_SPK_SAMPLES_SELECT);
#endif

#if ADAPTER_MAGIC_EN || ADAPTER_ECHO_EN
//魔音 或者 ECHO算法 和Reverb 同时开启时mute住 Reverb,以魔音 echo为主
#if ADAPTER_PLATE_REVERB_EN
        plate_reverb_audio_mute_set(1);
#endif

#endif
#if I2S_TX_AUDIO_EN
        iis_audio_out_init();
#endif
#if ADAPTER_LOACL_MIC_EN
        local_mic_init();
#endif
    }
    adapter_cb.init_state = ADAPTER_STA_INIT_IDLE;
}

AT(.text.func.adapter)
static void func_adapter_process_do(void)
{
    u8 link_nb;

    if(wireless_cb.change_flag) {
        wireless_cb.change_flag = 0;
        adapter_cb.init_state = ADAPTER_STA_START_ACTION;
    }

    switch(adapter_cb.init_state) {
    case ADAPTER_STA_INIT_IDLE:
        link_nb = bt_get_link_info_nb();
        TRACE("adapter, init(%d): %x, %d\n", wireless_mic_is_bonding(), wireless_cb.connected_sta, link_nb);

        if(link_nb != 0) {
            //有回连信息，等待被连接（关闭可被发现）
            ble_adv_set_enable(1, 0);
            adapter_cb.init_state  = ADAPTER_STA_INIT_W4_CONNECT;
            adapter_cb.ticks       = tick_get();
        } else {
            //没有回连信息，等待被发现和连接
            ble_adv_set_enable(1, 1);
            adapter_cb.init_state  = ADAPTER_STA_IDLE;
        }
        break;

    case ADAPTER_STA_INIT_W4_CONNECT:
        if(tick_check_expire(adapter_cb.ticks, 2000)) {
            adapter_cb.init_state = ADAPTER_STA_START_ACTION;
        }
        break;

    case ADAPTER_STA_START_ACTION:
        link_nb = bt_get_link_info_nb();
        TRACE("adapter, con_sta(%d): %x, %d\n", wireless_mic_is_bonding(), wireless_cb.connected_sta, link_nb);

        if(wireless_cb.connected_sta == WIRELESS_CON_STA_MASK) {
            //两个都连上了，关闭可被发现和可被连接
            ble_adv_set_enable(0, 0);
        } else if(wireless_mic_is_bonding() && link_nb >= WIRELESS_CON_LINK_NB) {
            //组队绑定时，切配对过两个，等待被连接（关闭可被发现）
            ble_adv_set_enable(1, 0);
        } else {
            //等待被发现和连接
            ble_adv_set_enable(1, 1);
        }
        adapter_cb.init_state = ADAPTER_STA_IDLE;
        break;
    }
}

AT(.text.func.process.adapter)
void func_adapter_process(void)
{
#if TRACE_EN
    static u8 sta = 0xff;
    if(sta != adapter_cb.init_state) {
        sta = adapter_cb.init_state;
        TRACE("adapter, state: %d\n", sta);
    }
#endif
    if(adapter_cb.init_state != ADAPTER_STA_IDLE || wireless_cb.change_flag) {
        func_adapter_process_do();
    }

    led_disp_proc();
    func_process();
#if ADAPTER_USB_MIC_RX_EN
    usb_device_process();
#endif

#if WIRELESS_MIC_BONDING_SWITCH_EN
     if(sys_cb.pair_delay == 0) {
        printf("sys_cb.pair_delay ==0\r\n");
        dis_pair_timer();//关闭定时器 避免频繁调用
        le_conn_set_conn_without_limit(0);//关闭弱绑定，20s后进入强绑定状态，只会回连绑定过的设备；（未发生过链接则不影响）
     }
#endif
}

AT(.text.func.adapter)
static void func_adapter_enter(void)
{
    func_adapter_init();
    func_bt_init();

}

AT(.text.func.adapter)
static void func_adapter_exit(void)
{
    le_mic_discon_all();
    bt_off();
    func_cb.last = FUNC_ADAPTER;
    sys_cb.bt_is_inited = 0;
    adapter_cb.init_flag = 0;
}

AT(.text.func.adapter)
void func_adapter(void)
{
    printf("%s\n", __func__);

    func_adapter_enter();

    while (func_cb.sta == FUNC_ADAPTER) {
        func_adapter_process();
        func_adapter_message(msg_dequeue());
        //func_adapter_display();
    }

    func_adapter_exit();
}

